/** 
* @file entrypoint.cpp 
* Kernel Entry point.
*
* This code is called directly from kernel loader (rkldr.sys)
* at bootloading procedure.
*
* Copyrights 2010 Michal Saman, m.saman@designplus.cz.
* This source code is release under the Apache License 2.0.
* http://www.apache.org/licenses/LICENSE-2.0
*/

#include <main/boot_info.h>
#include <main/kprintf.h>
#include <stdint.h>

/** Global variable for multi boot structure, obtained from bootloader. */
struct mboot_info_t* _boot_info;
/** Global variable for init_stack_addr, obtained from bootloader. */
uint32_t _init_stack_addr;

extern void main () __attribute__ ((cdecl));
//extern void InitializeConstructors() __attribute__ ((cdecl));
//extern void Exit () __attribute__ ((cdecl));

void __attribute__ ((cdecl)) __attribute__ ((section (".entry_point"))) kernel_entry (struct mboot_info_t *bi, uint32_t init_stack_addr) {

	//DebugGetCursorPos();
	//DebugSetColor(0x0);
	//DebugPrintf("KUK\n");

	/*
	unsigned char *p = (unsigned char*)0xB8000;
	int i;
	for (i=0; i<160*26; i+=2) {
		p[i] = 'A';
		p[i+1] = 0xE;
	}
	*/

	#ifdef ARCH_X86
		__asm__ volatile (
			"cli\n\t"						// clear interrupts
			"mov	$0x10, %ax\n\t"			// offset 0x10 in GDT for data selector
			"mov	%ax, %ds\n\t"
			"mov	%ax, %es\n\t"
			"mov	%ax, %fs\n\t"
			"mov	%ax, %gs\n\t"

			//"mov 	%ax, %ss\n\t"
			//"mov	$0x90000, %esp\n\t"
			//"mov	%esp, %ebp\n\t"
			//"push 	%ebp\n\t"
		);
	#endif

	// execute global constructors
	//InitializeConstructors();
	// set global var boot_info
	_boot_info = (struct mboot_info_t*)bi;
	_init_stack_addr = init_stack_addr;
	// call r-kernel entry point
	main();
	// cleanup all dynamic dtors
	//Exit();

	#ifdef ARCH_X86
		__asm__ volatile ("cli");
	#endif

	for (;;);
}
